package com.tanhua.server.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.server.enums.ConclusionEnum;
import com.tanhua.server.enums.CoverEnum;
import com.tanhua.server.mapper.*;
import com.tanhua.server.pojo.*;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.ConclusionVo;
import com.tanhua.server.vo.OptionsVo;
import com.tanhua.server.vo.PaperListVo;
import com.tanhua.server.vo.QuestionsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author YuShiLong
 * @Date 2021/4/27 16:13
 * @Version 1.0
 */
//由于问卷分为三个级别且是逐一解锁的,所以中级和高级应该是被锁住的,而初级是不能被锁住,应该定义三个不同的返回结果用来返回响应的问卷
@Service
public class TestSoulService {

    @Autowired
    private SoulReportMapper soulReportMapper;

    @Autowired
    private SoulPaperMapper soulPaperMapper;

    @Autowired
    private SoulPaperQuestionMapper soulPaperQuestionMapper;

    @Autowired
    private SoulQuestionMapper soulQuestionMapper;

    @Autowired
    private SoulOptionsMapper soulOptionsMapper;

    @Autowired
    private UserInfoService userInfoService;

    public List<PaperListVo> queryPaperList() {
        //获取当前的user对象
        User user = UserThreadLocal.get();

        //定义三个等级的问卷
        //初级问卷
        PaperListVo paperListVo1 = new PaperListVo();
        //中级问卷
        PaperListVo paperListVo2 = new PaperListVo();
        //高级问卷
        PaperListVo paperListVo3 = new PaperListVo();

        //调用方法,填充问卷
        fillTestSoul(paperListVo1, 1);
        fillTestSoul(paperListVo2, 2);
        fillTestSoul(paperListVo3, 3);

        //根据用户的id进行查询自己相应的报告
        QueryWrapper<SoulReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getId());
        List<SoulReport> soulReportList = this.soulReportMapper.selectList(queryWrapper);

        //判断报告返回的结果,根据报告返回的结果判断当前用户的问卷等级
        int size = soulReportList.size();
        if (size == 0) {
            //当前用户的报告为0,没有做个测试,所有解锁初级,锁定中级和高级
            paperListVo1.setIsLock(0);
            paperListVo2.setIsLock(1);
            paperListVo3.setIsLock(1);
        } else if (size == 1) {
            //当前用户的报告为1,做个一次测试,又因为报告只能逐级解锁,所以解锁中级,锁定高级
            paperListVo1.setIsLock(0);
            paperListVo2.setIsLock(0);
            paperListVo3.setIsLock(1);
            //获取该用户最新的报告
            for (SoulReport soulReport : soulReportList) {
                //拿到问卷表id为1的报告,其他报告设为空
                if (soulReport.getPaperId() == 1) {
                    paperListVo1.setReportId(soulReport.getId().toString());
                }
                paperListVo2.setReportId(null);
                paperListVo3.setReportId(null);
            }
        } else if (size == 2) {
            //当前用户的报告为1,说明此时用户已经完成初级,中级测试,那么要解锁高级
            paperListVo1.setIsLock(0);
            paperListVo2.setIsLock(0);
            paperListVo3.setIsLock(0);
            //拿到最新的报告id
            for (SoulReport soulReport : soulReportList) {
                if (soulReport.getPaperId() == 1) {
                    paperListVo1.setReportId(soulReport.getId().toString());
                }if (soulReport.getPaperId() == 2) {
                    paperListVo2.setReportId(soulReport.getId().toString());
                }
                paperListVo3.setReportId(null);
            }
        }else if (size == 3) {
            //解除锁住
            paperListVo1.setIsLock(0);
            paperListVo2.setIsLock(0);
            paperListVo3.setIsLock(0);
            //设置报告id
            for (SoulReport soulReport : soulReportList) {
                if (soulReport.getPaperId() == 1) {
                    paperListVo1.setReportId(soulReport.getId().toString());
                }
                if (soulReport.getPaperId() == 2) {
                    paperListVo2.setReportId(soulReport.getId().toString());
                }
                if (soulReport.getPaperId() == 3) {
                    paperListVo3.setReportId(soulReport.getId().toString());
                }
            }
        }

        List<PaperListVo> list = new ArrayList<>();
        list.add(paperListVo1);
        list.add(paperListVo2);
        list.add(paperListVo3);

        return list;
    }

    //定义一个方法根据不同的级别来填充问卷问题
    private void fillTestSoul(PaperListVo paperListVo, int id) {
        //根据SoulPaper之中的信息填充paperListVo
        //填充问卷id
        paperListVo.setId(String.valueOf(id));
        //填充问卷姓名
        paperListVo.setName(this.soulPaperMapper.selectById(id).getName());
        //填充问卷封面
        paperListVo.setCover(this.soulPaperMapper.selectById(id).getCover());
        //填充问卷级别
        paperListVo.setLevel(this.soulPaperMapper.selectById(id).getLevel());
        //填充问卷星级别
        paperListVo.setStar(this.soulPaperMapper.selectById(id).getStar());

        //构建查询条件,根据传入的id,填充不同的问卷
        QueryWrapper<SoulPaperQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("paper_id", id);
        List<SoulPaperQuestion> soulPaperQuestionList = this.soulPaperQuestionMapper.selectList(queryWrapper);

        //定义一个questionsVoList集合
        List<QuestionsVo> questionsVoList = new ArrayList<>();

        for (SoulPaperQuestion soulPaperQuestion : soulPaperQuestionList) {
            //封装QuestionsVo对象
            QuestionsVo questionsVo = new QuestionsVo();

            questionsVo.setId(soulPaperQuestion.getId().toString());
            //通过soulPaperQuestion查询到问题id,再通过soulQuestionMapper查询到对应的问题
            questionsVo.setQuestion(this.soulQuestionMapper.selectById(soulPaperQuestion.getQuestionId()).getQuestion());

            //根据questionid查询问题对应的选项
            QueryWrapper<SoulOptions> optionsQueryWrapper = new QueryWrapper<>();
            optionsQueryWrapper.eq("question_id", soulPaperQuestion.getQuestionId());
            List<SoulOptions> soulOptionsList = this.soulOptionsMapper.selectList(optionsQueryWrapper);

            //填充选项内容
            //创建一个集合得到一个问题所有的选项
            List<OptionsVo> optionsVoList = new ArrayList<>();
            for (SoulOptions soulOptions : soulOptionsList) {
                OptionsVo optionsVo = new OptionsVo();
                //前端页面需要的是选项id,也就是主键id
                optionsVo.setId(soulOptions.getId().toString());
                //添加选项
                optionsVo.setOption(soulOptions.getOptions());
                //添加到选项集合
                optionsVoList.add(optionsVo);
            }

            //将选项集合填充到问题中
            questionsVo.setOptions(optionsVoList);
            //将所有信息填充到问题集合中
            questionsVoList.add(questionsVo);
        }
        //添加到PaperListVo中
        paperListVo.setQuestions(questionsVoList);
    }


    public ConclusionVo getReport(String id) {
        //获取当前用户
        User user = UserThreadLocal.get();

        //创建ConclusionVo鉴定结果对象
        ConclusionVo conclusionVo = new ConclusionVo();

        //根据报告id获取report表中的数据
        QueryWrapper<SoulReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        SoulReport soulReport = soulReportMapper.selectOne(queryWrapper);

        //如果report表中没有数据,返回null
        if (null == soulReport) {
            return null;
        }

        //从report表中获取用户的得分
        Long score = soulReport.getScore();
        //再到report表中查询分数接近的用户,和自己分数相差10分以内,且不是自己,且答的是同一份问卷的其他用户
        QueryWrapper<SoulReport> queryListWrapper = new QueryWrapper<>();
        queryListWrapper
                .between("score", score - 10, score + 10)
                .ne("user_id", soulReport.getUserId())
                .eq("paper_id", soulReport.getPaperId());

        List<SoulReport> soulReportList = soulReportMapper.selectList(queryListWrapper);

        //获取这些分数相似的id
        Set<Long> userIds = new HashSet<>();
        for (SoulReport report : soulReportList) {
            userIds.add(report.getUserId());
        }

        //创建一个集合用来保存这些相似的人
        List<SoulSimilarYou> soulSimilarYouList = new ArrayList<>();

        //根据id查询相似分数的用户信息
        QueryWrapper<UserInfo> infoQueryWrapper = new QueryWrapper<>();
        infoQueryWrapper.in("user_id", userIds);
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(infoQueryWrapper);

        for (SoulReport report : soulReportList) {
            for (UserInfo userInfo : userInfoList) {
                if (report.getUserId().longValue() == userInfo.getUserId().longValue()) {
                    //说明id一致,可以进行填充
                    SoulSimilarYou soulSimilarYou = new SoulSimilarYou();
                    soulSimilarYou.setId(Integer.valueOf(report.getUserId().toString()));
                    soulSimilarYou.setAvatar(userInfo.getLogo());
                    //添加到soulSimilarYouList集合中
                    soulSimilarYouList.add(soulSimilarYou);
                }
            }
        }

        //根据不同的分数结果,给予不同的报告
        if (soulReport.getScore() < 21) {
            //如果分数小于,则判定为猫头鹰
            conclusionVo.setConclusion(ConclusionEnum.MAOTOUTING.getValue());
            //设置封面
            conclusionVo.setCover(CoverEnum.MAOTTOUYING.getValue());
            //创建一个集合用来保存维度
            List<SoulDimensions> dimensionsList = new ArrayList<>();
            //定义维度
            SoulDimensions s1 = new SoulDimensions("外向", "80%");
            SoulDimensions s2 = new SoulDimensions("判断", "70%");
            SoulDimensions s3 = new SoulDimensions("抽象", "90%");
            SoulDimensions s4 = new SoulDimensions("理性", "60%");
            //添加到维度集合中
            dimensionsList.add(s1);
            dimensionsList.add(s2);
            dimensionsList.add(s3);
            dimensionsList.add(s4);
            //添加到鉴定结果中
            conclusionVo.setDimensions(dimensionsList);
            conclusionVo.setSimilarYou(soulSimilarYouList);
        } else if (soulReport.getScore() >= 21 && soulReport.getScore() < 40) {
            //如果分数小于,则判定为白兔
            conclusionVo.setConclusion(ConclusionEnum.BAITU.getValue());
            //设置封面
            conclusionVo.setCover(CoverEnum.BAITU.getValue());
            //创建一个集合用来保存维度
            List<SoulDimensions> dimensionsList = new ArrayList<>();
            //定义维度
            SoulDimensions s1 = new SoulDimensions("外向", "90%");
            SoulDimensions s2 = new SoulDimensions("判断", "60%");
            SoulDimensions s3 = new SoulDimensions("抽象", "80%");
            SoulDimensions s4 = new SoulDimensions("理性", "70%");
            //添加到维度集合中
            dimensionsList.add(s1);
            dimensionsList.add(s2);
            dimensionsList.add(s3);
            dimensionsList.add(s4);
            //添加到鉴定结果中
            conclusionVo.setDimensions(dimensionsList);
            conclusionVo.setSimilarYou(soulSimilarYouList);
        } else if (soulReport.getScore() >= 41 && soulReport.getScore() < 55) {
            //如果分数小于,则判定为狐狸
            conclusionVo.setConclusion(ConclusionEnum.HULI.getValue());
            //设置封面
            conclusionVo.setCover(CoverEnum.HULI.getValue());
            //创建一个集合用来保存维度
            List<SoulDimensions> dimensionsList = new ArrayList<>();
            //定义维度
            SoulDimensions s1 = new SoulDimensions("外向", "70%");
            SoulDimensions s2 = new SoulDimensions("判断", "90%");
            SoulDimensions s3 = new SoulDimensions("抽象", "60%");
            SoulDimensions s4 = new SoulDimensions("理性", "80%");
            //添加到维度集合中
            dimensionsList.add(s1);
            dimensionsList.add(s2);
            dimensionsList.add(s3);
            dimensionsList.add(s4);
            //添加到鉴定结果中
            conclusionVo.setDimensions(dimensionsList);
            conclusionVo.setSimilarYou(soulSimilarYouList);
        } else if (soulReport.getScore() >= 56) {
            //如果分数小于,则判定为狮子
            conclusionVo.setConclusion(ConclusionEnum.SHIZI.getValue());
            //设置封面
            conclusionVo.setCover(CoverEnum.SHIZI.getValue());
            //创建一个集合用来保存维度
            List<SoulDimensions> dimensionsList = new ArrayList<>();
            //定义维度
            SoulDimensions s1 = new SoulDimensions("外向", "60%");
            SoulDimensions s2 = new SoulDimensions("判断", "80%");
            SoulDimensions s3 = new SoulDimensions("抽象", "70%");
            SoulDimensions s4 = new SoulDimensions("理性", "90%");
            //添加到维度集合中
            dimensionsList.add(s1);
            dimensionsList.add(s2);
            dimensionsList.add(s3);
            dimensionsList.add(s4);
            //添加到鉴定结果中
            conclusionVo.setDimensions(dimensionsList);
            conclusionVo.setSimilarYou(soulSimilarYouList);
        } else {
            return null;
        }
        return conclusionVo;

    }

    public String submitTestPaper(Map<String, List<Answers>> map) {

        //获取当前用户
        User user = UserThreadLocal.get();
        //设置初始分数和题目id为0
        Long score = 0L;
        Long questionId = 0L;

        //获取前端选择的选项集合
        Collection<List<Answers>> answersList = map.values();
        for (List<Answers> answers : answersList) {
            for (Answers answer : answers) {
                //获取题目id
                questionId = Long.valueOf(answer.getQuestionId());
                //获取选项的id
                String optionId = answer.getOptionId();
                //根据选项的id获取选项
                QueryWrapper<SoulOptions> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("question_id", questionId);
                queryWrapper.eq("id", optionId);
                //计算得分
                SoulOptions soulOptions1 = this.soulOptionsMapper.selectOne(queryWrapper);
                Long score1 = soulOptions1.getScore();
                score += score1;
            }
        }

        //构建查询条件,判断做的是那一套题
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("question_id", questionId);
        SoulPaperQuestion soulPaperQuestion = soulPaperQuestionMapper.selectOne(queryWrapper);
        //获取问卷id
        Long paperId = soulPaperQuestion.getPaperId();

        //查询该用户的报告id
        QueryWrapper<SoulReport> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("user_id", user.getId()).eq("paper_id", paperId);
        SoulReport result = this.soulReportMapper.selectOne(queryWrapper2);

        //判断报告是否为空
        if (null != result) {
            //不为空,代表该用户以前做过题,生成过报告,然后更新该报告信息
            QueryWrapper<SoulReport> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("user_id", UserThreadLocal.get().getId());
            SoulReport soulReport = new SoulReport();
            soulReport.setScore(score);
            soulReport.setUpdated(new Date(System.currentTimeMillis()));
            soulReportMapper.update(soulReport, queryWrapper1);

            //查询当前结果的ID返回
            QueryWrapper<SoulReport> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.eq("user_id", user.getId()).eq("paper_id", paperId);
            SoulReport soulReport1 = soulReportMapper.selectOne(queryWrapper3);
            return soulReport1.getId().toString();
        }

        //如果查不到那就插入到数据库
        SoulReport soulReport = new SoulReport();
        soulReport.setUserId(UserThreadLocal.get().getId());
        soulReport.setPaperId(paperId);
        soulReport.setScore(score);
        soulReport.setCreated(new Date(System.currentTimeMillis()));
        soulReport.setUpdated(new Date(System.currentTimeMillis()));
        soulReportMapper.insert(soulReport);

        //查询当前结果的ID返回
        QueryWrapper<SoulReport> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_id", user.getId()).eq("paper_id", paperId);
        SoulReport soulReport1 = soulReportMapper.selectOne(queryWrapper1);
        return soulReport1.getId().toString();
    }
}
